package com.toolbox.utils;



import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.RescaleOp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

public class ImageProcessor {

    // 注意：OpenCV库当前不可用，使用纯Java实现的证件照底色处理功能

    /**
     * 更换证件照底色（保留人像，替换背景）- 支持文件路径参数
     */
    public static BufferedImage changeBackground(String imagePath, String backgroundType) throws Exception {
        // 读取文件到字节数组
        byte[] imageBytes = Files.readAllBytes(Paths.get(imagePath));
        
        // 调用字节数组版本的方法进行处理
        byte[] processedBytes = changeBackground(imageBytes, backgroundType);
        
        // 将处理后的字节数组转换回BufferedImage
        try (ByteArrayInputStream bis = new ByteArrayInputStream(processedBytes)) {
            return ImageIO.read(bis);
        }
    }
    
    /**
     * 更换证件照底色（保留人像，替换背景）- 支持字节数组参数
     */
    public static byte[] changeBackground(byte[] imageBytes, String backgroundType) throws Exception {
        // 验证背景类型
        if (!backgroundType.equalsIgnoreCase("red") &&
            !backgroundType.equalsIgnoreCase("white") &&
            !backgroundType.equalsIgnoreCase("blue")) {
            throw new Exception("不支持的背景类型: " + backgroundType);
        }
        
        try {
            // 将字节数组转换为BufferedImage
            BufferedImage image;
            try (ByteArrayInputStream bis = new ByteArrayInputStream(imageBytes)) {
                image = ImageIO.read(bis);
            }
            
            // 预处理：增强图像对比度和锐度，提高后续处理效果
            BufferedImage preprocessedImage = preprocessImageForBackgroundRemoval(image);
            
            // 创建一个新的BufferedImage用于输出
            BufferedImage resultImage = new BufferedImage(
                preprocessedImage.getWidth(), preprocessedImage.getHeight(), BufferedImage.TYPE_INT_RGB
            );
            
            // 设置背景色 - 使用证件照标准颜色
            Graphics2D g2d = resultImage.createGraphics();
            
            // 根据背景类型设置颜色 - 使用证件照标准色值
            Color backgroundColor;
            if (backgroundType.equalsIgnoreCase("red")) {
                backgroundColor = new Color(255, 20, 60); // 证件照标准红色
            } else if (backgroundType.equalsIgnoreCase("blue")) {
                backgroundColor = new Color(67, 142, 219); // 证件照标准蓝色
            } else {
                backgroundColor = new Color(255, 255, 255); // 纯白色
            }
            
            // 填充背景色
            g2d.setColor(backgroundColor);
            g2d.fillRect(0, 0, preprocessedImage.getWidth(), preprocessedImage.getHeight());
            
            // 实现证件照底色处理（保留人像，替换背景）
            if (preprocessedImage.getColorModel().hasAlpha()) {
                // 对于带Alpha通道的图像，使用AlphaComposite.SRC_ATOP
                g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f));
                g2d.drawImage(preprocessedImage, 0, 0, null);
            } else {
                // 对于不带Alpha通道的图像，进行智能背景分割
                BufferedImage processedImage = performIntelligentBackgroundReplacement(preprocessedImage, backgroundColor);
                g2d.drawImage(processedImage, 0, 0, null);
            }
            
            g2d.dispose();
            
            // 最后进行一次全局优化，提高整体图像质量
            resultImage = finalImageEnhancement(resultImage, image);
            
            // 将结果转换回字节数组
            try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
                ImageIO.write(resultImage, "jpg", baos);
                baos.flush();
                return baos.toByteArray();
            }
        } catch (Exception e) {
            // 如果处理失败，返回原始图像
            System.err.println("图像处理失败: " + e.getMessage());
            e.printStackTrace();
            return imageBytes;
        }
    }
    
    /**
     * 图像预处理：增强对比度和锐度，提高背景分割效果
     */
    private static BufferedImage preprocessImageForBackgroundRemoval(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        
        // 增强对比度
        RescaleOp rescaleOp = new RescaleOp(1.2f, 15, null);
        result = rescaleOp.filter(image, result);
        
        // 轻微锐化
        float[] sharpeningKernel = {
            0, -1, 0,
            -1, 5, -1,
            0, -1, 0
        };
        Kernel kernel = new Kernel(3, 3, sharpeningKernel);
        ConvolveOp sharpeningOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
        result = sharpeningOp.filter(result, null);
        
        return result;
    }
    
    /**
     * 执行智能背景替换（证件照底色处理核心算法）
     */
    private static BufferedImage performIntelligentBackgroundReplacement(BufferedImage image, Color backgroundColor) {
        int width = image.getWidth();
        int height = image.getHeight();
        BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        
        // 1. 创建一个改进的精细蒙版，特别优化多人合照
        BufferedImage enhancedMask = createEnhancedMask(image);
        
        // 1.5 进一步优化蒙版，去除小的背景噪点
        enhancedMask = refineMaskForMultiPerson(enhancedMask);
        
        // 2. 进行背景替换，使用改进的混合算法
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int maskRGB = enhancedMask.getRGB(x, y);
                int maskGray = (maskRGB >> 16) & 0xFF;
                int imageRGB = image.getRGB(x, y);
                
                // 计算前景和背景的混合比例
                float alpha = maskGray / 255.0f;
                
                // 根据像素位置和周围环境自适应调整阈值 - 降低阈值以保留更多细节
                float adaptiveForegroundThreshold = calculateAdaptiveForegroundThreshold(x, y, maskGray, enhancedMask);
                float adaptiveBackgroundThreshold = adaptiveForegroundThreshold - 0.15f; // 减少阈值差距，扩大边缘过渡区域
                
                if (alpha > adaptiveForegroundThreshold) {
                    // 前景区域：完全保留原图
                    result.setRGB(x, y, imageRGB);
                } else if (alpha < adaptiveBackgroundThreshold) {
                    // 背景区域：完全替换为选定底色
                    result.setRGB(x, y, backgroundColor.getRGB());
                } else {
                    // 边缘区域：平滑过渡，优化抗锯齿处理
                    int rImg = (imageRGB >> 16) & 0xFF;
                    int gImg = (imageRGB >> 8) & 0xFF;
                    int bImg = imageRGB & 0xFF;
                    
                    int rBg = backgroundColor.getRed();
                    int gBg = backgroundColor.getGreen();
                    int bBg = backgroundColor.getBlue();
                    
                    // 改进的颜色混合算法，考虑边缘的平滑过渡
                    float smoothedAlpha = smoothAlphaForEdges(alpha, x, y, enhancedMask);
                    
                    // 计算混合颜色
                    int r = (int)(rImg * smoothedAlpha + rBg * (1 - smoothedAlpha));
                    int g = (int)(gImg * smoothedAlpha + gBg * (1 - smoothedAlpha));
                    int b = (int)(bImg * smoothedAlpha + bBg * (1 - smoothedAlpha));
                    
                    // 应用边缘颜色校正，使边缘更自然
                    int edgeCorrectedRGB = applyEdgeColorCorrection(r, g, b, smoothedAlpha, imageRGB, backgroundColor.getRGB());
                    result.setRGB(x, y, edgeCorrectedRGB);
                }
            }
        }
        
        // 3. 应用更精细的高斯模糊，使边缘更自然
        BufferedImage blurredResult = applyEnhancedGaussianBlur(result, 1);
        
        // 4. 增强人像细节，特别针对多人合照优化
        enhancePortraitDetails(blurredResult, image);
        
        // 5. 对背景进行额外处理，使颜色更均匀
        enhanceBackgroundWithMask(blurredResult, enhancedMask, backgroundColor);
        
        return blurredResult;
    }
    
    /**
     * 计算自适应前景阈值，根据图像区域特征动态调整
     */
    private static float calculateAdaptiveForegroundThreshold(int x, int y, int maskGray, BufferedImage mask) {
        // 基础阈值
        float baseThreshold = 0.7f;
        
        // 检查是否处于大面积前景区域，如果是则降低阈值以保留更多细节
        int foregroundPixelCount = countForegroundPixels(x, y, 10, mask);
        
        // 如果周围80%以上都是前景像素，则降低阈值
        if (foregroundPixelCount > 80) {
            return 0.65f;
        }
        
        return baseThreshold;
    }
    
    /**
     * 计算指定区域内的前景像素数量百分比
     */
    private static int countForegroundPixels(int x, int y, int radius, BufferedImage mask) {
        int width = mask.getWidth();
        int height = mask.getHeight();
        int totalPixels = 0;
        int foregroundPixels = 0;
        
        for (int ky = -radius; ky <= radius; ky++) {
            for (int kx = -radius; kx <= radius; kx++) {
                int nx = x + kx;
                int ny = y + ky;
                if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
                    totalPixels++;
                    int maskGray = (mask.getRGB(nx, ny) >> 16) & 0xFF;
                    if (maskGray > 180) {
                        foregroundPixels++;
                    }
                }
            }
        }
        
        return totalPixels > 0 ? (foregroundPixels * 100) / totalPixels : 0;
    }
    
    /**
     * 应用边缘颜色校正，使边缘过渡更自然
     */
    private static int applyEdgeColorCorrection(int r, int g, int b, float alpha, int imageRGB, int bgRGB) {
        // 从原图提取更多色彩信息，特别是在边缘区域
        int rImg = (imageRGB >> 16) & 0xFF;
        int gImg = (imageRGB >> 8) & 0xFF;
        int bImg = imageRGB & 0xFF;
        
        // 在边缘区域保留更多原图的颜色信息
        if (alpha > 0.3 && alpha < 0.7) {
            // 轻微调整色调，使边缘更自然
            float correctionFactor = 0.15f * (0.7f - alpha) / 0.4f;
            r = (int)(r + (rImg - r) * correctionFactor);
            g = (int)(g + (gImg - g) * correctionFactor);
            b = (int)(b + (bImg - b) * correctionFactor);
        }
        
        return new Color(clamp(r), clamp(g), clamp(b)).getRGB();
    }
    
    /**
     * 将颜色值限制在0-255范围内
     */
    private static int clamp(int value) {
        return Math.min(255, Math.max(0, value));
    }
    
    /**
     * 为多人合照优化蒙版，去除小的背景噪点
     */
    private static BufferedImage refineMaskForMultiPerson(BufferedImage mask) {
        int width = mask.getWidth();
        int height = mask.getHeight();
        BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
        
        // 先进行一次膨胀操作，连接分散的前景区域
        result = applyMorphologicalOperations(mask);
        
        // 再进行一次高斯模糊，平滑边缘
        result = applyEnhancedGaussianBlur(result, 1);
        
        // 二次阈值处理，强化前景区域
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rgb = result.getRGB(x, y);
                int gray = (rgb >> 16) & 0xFF;
                // 降低阈值以保留更多头发等细节
                int maskValue = (gray > 80) ? 255 : 0;
                result.setRGB(x, y, new Color(maskValue, maskValue, maskValue).getRGB());
            }
        }
        
        return result;
    }
    
    /**
     * 优化边缘区域的alpha值，使过渡更自然
     */
    private static float smoothAlphaForEdges(float alpha, int x, int y, BufferedImage mask) {
        int width = mask.getWidth();
        int height = mask.getHeight();
        float alphaSum = 0;
        int count = 0;
        int radius = 3; // 增加半径以获得更平滑的边缘
        
        // 使用加权平均计算周围像素的alpha值，越近的像素权重越大
        for (int ky = -radius; ky <= radius; ky++) {
            for (int kx = -radius; kx <= radius; kx++) {
                int nx = x + kx;
                int ny = y + ky;
                if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
                    // 计算距离权重
                    double distance = Math.sqrt(kx * kx + ky * ky);
                    double weight = Math.exp(-distance * distance / (2 * 2.0)); // 高斯权重
                    
                    int maskRGB = mask.getRGB(nx, ny);
                    int maskGray = (maskRGB >> 16) & 0xFF;
                    alphaSum += (maskGray / 255.0f) * weight;
                    count += weight;
                }
            }
        }
        
        // 返回加权平均值，增加当前像素权重，保留更多细节
        float avgAlpha = alphaSum / count;
        return (alpha * 0.8f + avgAlpha * 0.2f); // 增加当前像素权重
    }
    
    /**
     * 创建更精细的图像蒙版，用于证件照人像分割
     */
    private static BufferedImage createEnhancedMask(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        BufferedImage mask = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
        
        // 1. 预处理：先进行高斯模糊，减少噪点，但保持边缘细节
        BufferedImage blurredImage = applyEnhancedGaussianBlur(image, 1);
        
        // 2. 创建颜色蒙版和边缘蒙版
        BufferedImage colorMask = createColorBasedMask(blurredImage);
        BufferedImage edges = detectEdgesEnhanced(blurredImage);
        
        // 3. 结合颜色蒙版和边缘蒙版 - 增加边缘蒙版的权重以保留更多细节
        BufferedImage combinedMask = combineMasks(colorMask, edges);
        
        // 4. 基于颜色和纹理的自适应阈值处理
        int threshold = calculateAdaptiveThreshold(combinedMask);
        
        // 5. 应用阈值并进行形态学处理 - 优化阈值应用，增加边缘细节保留
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rgb = combinedMask.getRGB(x, y);
                int gray = (rgb >> 16) & 0xFF;
                
                // 使用动态阈值提高蒙版质量 - 降低阈值以保留更多细节
                int adjustedThreshold = Math.min(threshold, 120); // 确保阈值不会过高
                int maskValue = (gray > adjustedThreshold) ? 255 : 0;
                mask.setRGB(x, y, new Color(maskValue, maskValue, maskValue).getRGB());
            }
        }
        
        // 6. 形态学操作：腐蚀和膨胀，去除小的噪点
        mask = applyMorphologicalOperations(mask);
        
        // 7. 平滑蒙版边缘 - 增加模糊半径以获得更平滑的边缘
        mask = applyEnhancedGaussianBlur(mask, 1);
        
        // 8. 额外的蒙版优化，特别针对多人合照
        mask = optimizeMaskForComplexScenes(mask);
        
        return mask;
    }
    
    /**
     * 创建基于颜色的蒙版，区分前景和背景
     */
    private static BufferedImage createColorBasedMask(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        BufferedImage mask = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
        
        // 转换为HSV色彩空间进行处理
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rgb = image.getRGB(x, y);
                int r = (rgb >> 16) & 0xFF;
                int g = (rgb >> 8) & 0xFF;
                int b = rgb & 0xFF;
                
                // 计算HSV值
                float[] hsv = new float[3];
                Color.RGBtoHSB(r, g, b, hsv);
                float hue = hsv[0];
                float saturation = hsv[1];
                float value = hsv[2];
                
                // 基于HSV值创建颜色蒙版
                // 低饱和度和高亮度的区域更可能是背景
                int maskValue;
                if (saturation < 0.25 && value > 0.7) {
                    // 可能是白色背景
                    maskValue = 0;
                } else if ((hue > 0.9 || hue < 0.1) && saturation > 0.4 && value > 0.4) {
                    // 可能是红色背景
                    maskValue = 0;
                } else if (hue > 0.5 && hue < 0.7 && saturation > 0.4) {
                    // 可能是蓝色背景
                    maskValue = 0;
                } else {
                    // 可能是前景
                    maskValue = 255;
                }
                
                mask.setRGB(x, y, new Color(maskValue, maskValue, maskValue).getRGB());
            }
        }
        
        return mask;
    }
    
    /**
     * 结合颜色蒙版和边缘蒙版
     */
    private static BufferedImage combineMasks(BufferedImage colorMask, BufferedImage edgeMask) {
        int width = colorMask.getWidth();
        int height = colorMask.getHeight();
        BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
        
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int colorGray = (colorMask.getRGB(x, y) >> 16) & 0xFF;
                int edgeGray = (edgeMask.getRGB(x, y) >> 16) & 0xFF;
                
                // 增加边缘蒙版的权重，特别是对于细节丰富的区域
                // 对于边缘明显的区域，增加边缘蒙版的权重
                float edgeWeight = (edgeGray > 100) ? 0.45f : 0.35f;
                float colorWeight = 1.0f - edgeWeight;
                
                int combinedGray = (int)(colorGray * colorWeight + edgeGray * edgeWeight);
                combined.setRGB(x, y, new Color(combinedGray, combinedGray, combinedGray).getRGB());
            }
        }
        
        return combined;
    }
    
    /**
     * 改进的边缘检测算法，更适合人像分割
     */
    private static BufferedImage detectEdgesEnhanced(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        BufferedImage edges = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
        
        // 使用水平和垂直方向的Sobel算子进行边缘检测
        float[] sobelX = {-1, 0, 1, -2, 0, 2, -1, 0, 1};
        float[] sobelY = {1, 2, 1, 0, 0, 0, -1, -2, -1};
        
        Kernel kernelX = new Kernel(3, 3, sobelX);
        Kernel kernelY = new Kernel(3, 3, sobelY);
        
        BufferedImageOp opX = new ConvolveOp(kernelX, ConvolveOp.EDGE_NO_OP, null);
        BufferedImageOp opY = new ConvolveOp(kernelY, ConvolveOp.EDGE_NO_OP, null);
        
        BufferedImage edgesX = opX.filter(image, null);
        BufferedImage edgesY = opY.filter(image, null);
        
        // 合并两个方向的边缘
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rX = (edgesX.getRGB(x, y) >> 16) & 0xFF;
                int rY = (edgesY.getRGB(x, y) >> 16) & 0xFF;
                
                // 计算梯度大小，增加对比度
                int gradient = (int)Math.sqrt(rX * rX + rY * rY);
                // 归一化到0-255，提高边缘清晰度
                gradient = Math.min(255, (int)(gradient * 1.4)); // 增加对比度系数
                
                edges.setRGB(x, y, new Color(gradient, gradient, gradient).getRGB());
            }
        }
        
        return edges;
    }
    
    /**
     * 计算自适应阈值，考虑图像的不同区域
     */
    private static int calculateAdaptiveThreshold(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        int[][] histogram = new int[256][1];
        
        // 计算直方图
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rgb = image.getRGB(x, y);
                int gray = (rgb >> 16) & 0xFF;
                histogram[gray][0]++;
            }
        }
        
        // 使用Otsu算法计算最佳阈值
        return calculateOptimalThreshold(histogram, width * height);
    }
    
    /**
     * 为复杂场景优化蒙版，特别是多人合照
     */
    private static BufferedImage optimizeMaskForComplexScenes(BufferedImage mask) {
        int width = mask.getWidth();
        int height = mask.getHeight();
        BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
        
        // 应用中值滤波，保留边缘的同时去除噪点
        for (int y = 1; y < height - 1; y++) {
            for (int x = 1; x < width - 1; x++) {
                // 收集3x3邻域的像素值
                int[] neighbors = new int[9];
                int idx = 0;
                for (int ky = -1; ky <= 1; ky++) {
                    for (int kx = -1; kx <= 1; kx++) {
                        int neighborRGB = mask.getRGB(x + kx, y + ky);
                        neighbors[idx++] = (neighborRGB >> 16) & 0xFF;
                    }
                }
                
                // 排序并取中值
                java.util.Arrays.sort(neighbors);
                int median = neighbors[4];
                
                result.setRGB(x, y, new Color(median, median, median).getRGB());
            }
        }
        
        // 增强对比度，使前景和背景区分更明显
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rgb = result.getRGB(x, y);
                int gray = (rgb >> 16) & 0xFF;
                
                // 增强对比度：暗的更暗，亮的更亮
                int enhancedGray = (gray > 100) ? 255 : 0; // 降低阈值以保留更多细节
                result.setRGB(x, y, new Color(enhancedGray, enhancedGray, enhancedGray).getRGB());
            }
        }
        
        return result;
    }
    
    /**
     * 应用形态学操作（腐蚀和膨胀）
     */
    private static BufferedImage applyMorphologicalOperations(BufferedImage mask) {
        int width = mask.getWidth();
        int height = mask.getHeight();
        BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
        
        // 简单的形态学操作：腐蚀后膨胀，去除噪点
        // 腐蚀
        for (int y = 1; y < height - 1; y++) {
            for (int x = 1; x < width - 1; x++) {
                int minGray = 255;
                // 检查3x3邻域
                for (int ky = -1; ky <= 1; ky++) {
                    for (int kx = -1; kx <= 1; kx++) {
                        int neighborGray = (mask.getRGB(x + kx, y + ky) >> 16) & 0xFF;
                        if (neighborGray < minGray) {
                            minGray = neighborGray;
                        }
                    }
                }
                result.setRGB(x, y, new Color(minGray, minGray, minGray).getRGB());
            }
        }
        
        // 膨胀
        BufferedImage dilatedResult = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
        for (int y = 1; y < height - 1; y++) {
            for (int x = 1; x < width - 1; x++) {
                int maxGray = 0;
                // 检查3x3邻域
                for (int ky = -1; ky <= 1; ky++) {
                    for (int kx = -1; kx <= 1; kx++) {
                        int neighborGray = (result.getRGB(x + kx, y + ky) >> 16) & 0xFF;
                        if (neighborGray > maxGray) {
                            maxGray = neighborGray;
                        }
                    }
                }
                dilatedResult.setRGB(x, y, new Color(maxGray, maxGray, maxGray).getRGB());
            }
        }
        
        return dilatedResult;
    }
    
    /**
     * 增强人像细节
     */
    private static void enhancePortraitDetails(BufferedImage result, BufferedImage original) {
        int width = result.getWidth();
        int height = result.getHeight();
        
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int resultRGB = result.getRGB(x, y);
                int originalRGB = original.getRGB(x, y);
                
                // 获取alpha通道值
                int alpha = (resultRGB >> 24) & 0xFF;
                
                // 如果是前景区域且alpha值较高，保留更多原图细节
                if (alpha > 150) { // 降低阈值以处理更多边缘细节
                    // 混合原图和结果图，保留更多原图细节
                    int rResult = (resultRGB >> 16) & 0xFF;
                    int gResult = (resultRGB >> 8) & 0xFF;
                    int bResult = resultRGB & 0xFF;
                    
                    int rOriginal = (originalRGB >> 16) & 0xFF;
                    int gOriginal = (originalRGB >> 8) & 0xFF;
                    int bOriginal = originalRGB & 0xFF;
                    
                    // 根据alpha值动态调整混合比例
                    float originalWeight = 0.7f + (alpha - 150) * 0.3f / 105; // 原图权重动态调整
                    float resultWeight = 1.0f - originalWeight;
                    
                    int r = (int)(rOriginal * originalWeight + rResult * resultWeight);
                    int g = (int)(gOriginal * originalWeight + gResult * resultWeight);
                    int b = (int)(bOriginal * originalWeight + bResult * resultWeight);
                    
                    result.setRGB(x, y, new Color(r, g, b).getRGB());
                }
            }
        }
    }
    
    /**
     * 计算最佳阈值
     */
    private static int calculateOptimalThreshold(int[][] histogram, int totalPixels) {
        // 简单的Otsu阈值算法实现
        double sum = 0;
        for (int i = 0; i < 256; i++) {
            sum += i * histogram[i][0];
        }
        
        double sumB = 0;
        int wB = 0;
        int wF = 0;
        double maxVariance = 0;
        int threshold = 0;
        
        for (int i = 0; i < 256; i++) {
            wB += histogram[i][0];
            if (wB == 0) continue;
            
            wF = totalPixels - wB;
            if (wF == 0) break;
            
            sumB += (double)i * histogram[i][0];
            
            double mB = sumB / wB;
            double mF = (sum - sumB) / wF;
            
            double variance = (double)wB * (double)wF * (mB - mF) * (mB - mF);
            
            if (variance > maxVariance) {
                maxVariance = variance;
                threshold = i;
            }
        }
        
        return threshold;
    }
    
    /**
     * 应用高斯模糊
     */
    private static BufferedImage applyGaussianBlur(BufferedImage image, int radius) {
        int width = image.getWidth();
        int height = image.getHeight();
        BufferedImage result = new BufferedImage(width, height, image.getType());
        
        float weight = 1.0f / (2 * radius + 1);
        float[] data = new float[(2 * radius + 1) * (2 * radius + 1)];
        
        for (int i = 0; i < data.length; i++) {
            data[i] = weight;
        }
        
        Kernel kernel = new Kernel(2 * radius + 1, 2 * radius + 1, data);
        BufferedImageOp op = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
        
        return op.filter(image, result);
    }
    
    /**
     * 应用增强版高斯模糊，更适合边缘处理
     */
    private static BufferedImage applyEnhancedGaussianBlur(BufferedImage image, int radius) {
        // 使用更接近真实高斯分布的卷积核
        int size = 2 * radius + 1;
        float[] gaussianKernel = new float[size * size];
        
        // 计算高斯分布权重
        float sigma = radius * 0.6f; // 稍微增加sigma以获得更平滑的效果
        float sum = 0.0f;
        int center = radius;
        
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                float distance = (float)Math.sqrt((i - center) * (i - center) + (j - center) * (j - center));
                gaussianKernel[i * size + j] = (float)Math.exp(-distance * distance / (2 * sigma * sigma));
                sum += gaussianKernel[i * size + j];
            }
        }
        
        // 归一化
        for (int i = 0; i < gaussianKernel.length; i++) {
            gaussianKernel[i] /= sum;
        }
        
        Kernel kernel = new Kernel(size, size, gaussianKernel);
        BufferedImageOp op = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
        
        return op.filter(image, null);
    }
    
    /**
     * 创建简单的图像蒙版，用于分离前景和背景
     */
    private static BufferedImage createSimpleMask(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        BufferedImage mask = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
        
        // 简单的边缘检测算法
        float[] data = {-1, -1, -1, -1, 8, -1, -1, -1, -1};
        Kernel kernel = new Kernel(3, 3, data);
        BufferedImageOp op = new ConvolveOp(kernel);
        BufferedImage edges = op.filter(image, null);
        
        // 二值化处理
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rgb = edges.getRGB(x, y);
                int gray = (rgb >> 16) & 0xFF;
                // 阈值处理
                int maskValue = (gray > 30) ? 255 : 0;
                mask.setRGB(x, y, new Color(maskValue, maskValue, maskValue).getRGB());
            }
        }
        
        return mask;
    }
    
    /**
     * 使用蒙版增强背景效果
     */
    private static void enhanceBackgroundWithMask(BufferedImage resultImage, BufferedImage mask, Color backgroundColor) {
        int width = resultImage.getWidth();
        int height = resultImage.getHeight();
        
        // 创建一个临时图像用于背景处理
        BufferedImage tempImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = tempImage.createGraphics();
        
        // 填充纯背景色
        g2d.setColor(backgroundColor);
        g2d.fillRect(0, 0, width, height);
        
        // 对背景进行轻微模糊，使颜色更均匀
        BufferedImage backgroundBlur = applyEnhancedGaussianBlur(tempImage, 4); // 增加模糊半径
        
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int maskRGB = mask.getRGB(x, y);
                int gray = (maskRGB >> 16) & 0xFF;
                
                // 根据蒙版混合原图和处理后的背景 - 扩大背景处理范围，改善边缘融合
                if (gray < 220) {  // 进一步扩大背景处理范围
                    // 混合原始图像和背景色
                    int imageRGB = resultImage.getRGB(x, y);
                    int bgRGB = backgroundBlur.getRGB(x, y);
                    
                    int rImg = (imageRGB >> 16) & 0xFF;
                    int gImg = (imageRGB >> 8) & 0xFF;
                    int bImg = imageRGB & 0xFF;
                    
                    int rBg = (bgRGB >> 16) & 0xFF;
                    int gBg = (bgRGB >> 8) & 0xFF;
                    int bBg = bgRGB & 0xFF;
                    
                    // 根据灰色值计算混合比例 - 优化混合曲线，使过渡更自然
                    float bgRatio = 1.0f - (gray / 220.0f);
                    
                    // 应用平滑的混合曲线，使边缘过渡更自然
                    if (bgRatio > 0.1 && bgRatio < 0.9) {
                        // S-curve混合，使过渡更平滑
                        bgRatio = (float)(0.5 - 0.5 * Math.cos(bgRatio * Math.PI));
                    }
                    
                    // 对于非常接近背景的区域，应用更强的背景色
                    if (gray < 50) {
                        bgRatio = Math.min(0.98f, bgRatio + 0.2f);
                    }
                    
                    int r = (int)(rImg * (1 - bgRatio) + rBg * bgRatio);
                    int g = (int)(gImg * (1 - bgRatio) + gBg * bgRatio);
                    int b = (int)(bImg * (1 - bgRatio) + bBg * bgRatio);
                    
                    resultImage.setRGB(x, y, new Color(r, g, b).getRGB());
                }
            }
        }
        
        g2d.dispose();
    }

    /**
     * 最后图像增强，提高整体质量
     */
    private static BufferedImage finalImageEnhancement(BufferedImage processedImage, BufferedImage originalImage) {
        int width = processedImage.getWidth();
        int height = processedImage.getHeight();
        BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        
        // 应用轻微的锐化，使整体图像更清晰 - 调整锐化参数，避免过度锐化导致噪点
        float[] sharpeningKernel = {
            0, -0.4f, 0,
            -0.4f, 2.6f, -0.4f,
            0, -0.4f, 0
        };
        Kernel kernel = new Kernel(3, 3, sharpeningKernel);
        ConvolveOp sharpeningOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
        result = sharpeningOp.filter(processedImage, result);
        
        // 颜色校正，使肤色更自然 - 改进肤色检测算法，增加细节保护
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rgb = result.getRGB(x, y);
                int r = (rgb >> 16) & 0xFF;
                int g = (rgb >> 8) & 0xFF;
                int b = rgb & 0xFF;
                
                // 更精确的肤色检测和校正
                // 1. 转换到YCbCr颜色空间进行更好的肤色检测
                int yCbCrY = (int)(0.299 * r + 0.587 * g + 0.114 * b);
                int yCbCrCb = (int)(128 - 0.168736 * r - 0.331264 * g + 0.5 * b);
                int yCbCrCr = (int)(128 + 0.5 * r - 0.418688 * g - 0.081312 * b);
                
                // 2. 更精确的肤色范围检测
                boolean isSkin = yCbCrY > 50 && yCbCrCb > 77 && yCbCrCb < 127 && 
                                yCbCrCr > 133 && yCbCrCr < 173;
                
                if (isSkin) {
                    // 肤色区域，根据原始图像的色彩信息进行智能调整
                    int originalRGB = originalImage.getRGB(x, y);
                    int originalR = (originalRGB >> 16) & 0xFF;
                    int originalG = (originalRGB >> 8) & 0xFF;
                    int originalB = originalRGB & 0xFF;
                    
                    // 保留原始图像的肤色特征，但应用背景色校正
                    float skinPreservationFactor = 0.8f; // 保留80%的原始肤色特征
                    r = (int)(r * (1 - skinPreservationFactor) + originalR * skinPreservationFactor);
                    g = (int)(g * (1 - skinPreservationFactor) + originalG * skinPreservationFactor);
                    b = (int)(b * (1 - skinPreservationFactor) + originalB * skinPreservationFactor);
                    
                    // 轻微调整肤色色调，使其更自然
                    r = (int)(r * 1.01);
                    g = (int)(g * 1.01);
                    b = (int)(b * 0.99);
                }
                
                // 确保颜色值在有效范围内
                r = clamp(r);
                g = clamp(g);
                b = clamp(b);
                
                result.setRGB(x, y, new Color(r, g, b).getRGB());
            }
        }
        
        return result;
    }

    /**
     * 裁剪图片为标准证件照尺寸
     */
    public static byte[] cropToIDPhoto(byte[] imageBytes, int width, int height) throws Exception {
        // 将字节数组转换为BufferedImage
        BufferedImage image;
        try (ByteArrayInputStream bis = new ByteArrayInputStream(imageBytes)) {
            image = ImageIO.read(bis);
        }
        
        // 计算裁剪区域（从中心裁剪）
        int imageWidth = image.getWidth();
        int imageHeight = image.getHeight();
        
        double targetRatio = (double) width / height;
        double currentRatio = (double) imageWidth / imageHeight;
        
        int cropX, cropY, cropWidth, cropHeight;
        
        if (currentRatio > targetRatio) {
            // 宽高比大于目标，按高度裁剪
            cropHeight = imageHeight;
            cropWidth = (int) (imageHeight * targetRatio);
            cropX = (imageWidth - cropWidth) / 2;
            cropY = 0;
        } else {
            // 宽高比小于目标，按宽度裁剪
            cropWidth = imageWidth;
            cropHeight = (int) (imageWidth / targetRatio);
            cropX = 0;
            cropY = (imageHeight - cropHeight) / 2;
        }
        
        // 裁剪图像
        BufferedImage croppedImage = image.getSubimage(cropX, cropY, cropWidth, cropHeight);
        
        // 调整大小到目标尺寸
        BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = resizedImage.createGraphics();
        // 使用高质量缩放
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(croppedImage, 0, 0, width, height, null);
        g.dispose();
        
        // 将结果转换回字节数组
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            ImageIO.write(resizedImage, "jpg", baos);
            baos.flush();
            return baos.toByteArray();
        }
    }

    /**
     * 创建临时图像文件
     */
    public static File createTempImageFile(byte[] imageBytes, String extension) throws IOException {
        String tempDir = System.getProperty("java.io.tmpdir");
        String fileName = "image_" + UUID.randomUUID().toString() + "." + extension;
        File tempFile = new File(tempDir, fileName);
        
        try (ByteArrayInputStream bis = new ByteArrayInputStream(imageBytes);
             FileOutputStream fos = new FileOutputStream(tempFile)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = bis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
        }
        
        return tempFile;
    }
}